package cn.tedu.file;

import java.io.*;
import java.util.Scanner;

/*本类用于实现IO综合练习之文件复制案例,,,文件复制*/
public class TestCopyFile {
    public static void main(String[] args) {
        //1.提示并接收用户输入的两个路径
        System.out.println("请输入源文件路径:");
        String f = new Scanner(System.in).nextLine();
        System.out.println("请输入新文件路径:");
        String t = new Scanner(System.in).nextLine();

        //2.调用自己创建好的方法完成文件的复制
//        ZFCopy(f,t);
        ZJCopy(f,t); //字节方式包含字符方式
    }
    //本方法使用字节流完成文件的复制
    private static void ZJCopy(String f, String t) {
        //1.定义在整个方法中都生效的局部变量,注意手动初始化,默认值为null
        BufferedInputStream in = null;//高效子类变量
        BufferedOutputStream out = null;
        //2.由于IO操作可能会抛出异常,所以需要完成try-catch-finally结构
        try {
            //3.创建流对象
            in = new BufferedInputStream(new FileInputStream(f));//父类InputStream无法instantiate
            out = new BufferedOutputStream(new FileOutputStream(t,true));

            //4.使用流对象完成业务,边读边写
            //4.1定义变量,用来保存读到的数据
            int b ;
            //4.2循环读取文件中的内容,只要读到的数据不是-1,说明还有数据,继续
            while((b=in.read())!=-1){
                //4.3将读到的数据b写出到新文件中/新文件中
                out.write(b); //out含有新路径和文件                           //创建的新的路径对象文件,也会形成追加
            }
            System.out.println("恭喜您!文件复制成功!");
        }catch (Exception e){
            System.out.println("很抱歉!文件复制失败!");
            e.printStackTrace();
        }finally {
            //5.关流
            try {
                out.close();//关流顺序,后创建的流先关闭
            } /*catch (IOException e) {
                e.printStackTrace();
            }*/ catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                in.close();//每个流关闭时都有可能发生IO异常,需要单独try-catch
            } /*catch (IOException e) {
                e.printStackTrace();
            }*/ catch (IOException e) {
                throw new RuntimeException(e); //可能idea,
            }
        }
    }
    //本方法使用字符流完成文件的复制
    private static void ZFCopy(String f, String t) {
        //1.定义在整个方法中都生效的局部变量,注意手动初始化,默认值为null
        Reader in = null;
        Writer out = null;
        //2.由于代码可能会发生异常,所以需要编写try-catch-finally结构
        try{
            //3.1创建高效字符输入流对象//高效字符输入
            in = new BufferedReader(new FileReader(f));
            //3.2创建高效字符输出流对象//高效字符输出
            out = new BufferedWriter(new FileWriter(t,true));//可以追加输出字符

            //4.创建好流对象以后,就可以使用流对象来完成业务了
            //4.1定义变量用来保存读到的数据
            int b;
            //4.2循环读取源文件,直到返回值为-1,说明没数据了,就结束循环
            while((b = in.read()) != -1){
                //4.3将本轮循环读取到的数据写入到新文件中
                out.write(b);
            }
            System.out.println("恭喜您!文件复制成功!");
        }catch (Exception e){
            System.out.println("很抱歉!文件复制失败!");
            e.printStackTrace();
        }finally {
            /*1.关流是有顺序的,如果有多个流,最后创建的流要最先关闭
             * 2.多条关流语句需要各自try-catch*/
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
